/*!
\copyright  Copyright (c) 2020 Qualcomm Technologies International, Ltd.\n
            All Rights Reserved.\n
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file       headset_ragion_config.c
\brief     operating region configuration table

    This file contains battery operating configuration tables
*/

#include "headset_region_config.h"
#include "battery_region.h"
#include "charger_monitor.h"
#include "power_manager.h"
#include <rtime.h>
#include <logging.h>

#define REGION_MESSAGE_BATTERY_LOW 0

/* PSKey configurable sniff parameters */
typedef struct
{
    TaskData task;
    bool charging;
    bool batteryLowNotifying;
} regionTaskData;

regionTaskData regionData = {0};

/*! \brief charge mode config table*/
const charge_region_t headset_charge_mode_config_table[] =
{
    {0,       Vfloat,   4200, 50, -40, 0,  1, NORMAL_REGION, 0},
    {0,       Vfloat,   4200, 50,  0,  45, 1, NORMAL_REGION, 0},
    {0,       Vfloat,   4200, 50,  45, 85, 1, NORMAL_REGION, 0},
    {0,         3600, Vfloat, 50,  -40, 0,  1, NORMAL_REGION, 0},
    {FAST,      3600, Vfloat, 50,    0, 45, 1, NORMAL_REGION, CHARGING_TIMER_TIMEOUT},
    {0,         3600, Vfloat, 50,   45, 85, 1, NORMAL_REGION, 0},    
    {0,        Vcrit,   3600, 50,  -40, 0,  1, NORMAL_REGION, 0},
    {FAST,     Vcrit,   3600, 50,    0, 45, 1, NORMAL_REGION, CHARGING_TIMER_TIMEOUT},
    {0,        Vcrit,   3600, 50,   45, 85, 1, NORMAL_REGION, 0},    
    {0,        Vfast,  Vcrit, 50,  -40, 0,  1, CRITICAL_REGION, 0},
    {FAST,     Vfast,  Vcrit, 50,    0, 45, 1, CRITICAL_REGION, 0},
    {0,        Vfast,  Vcrit, 50,   45, 85, 1, CRITICAL_REGION, 0},    
    {0,         Vpre,  Vfast, 50,  -40, 0,  1, CRITICAL_REGION, 0},
    {PRE,       Vpre,  Vfast, 50,    0, 45, 1, CRITICAL_REGION, 0},
    {0,         Vpre,  Vfast, 50,   45, 85, 1, CRITICAL_REGION, 0},
    {0,            0,   Vpre, 50,  -40, 0,  1, CRITICAL_REGION, 0},
    {TRICKLE,      0,   Vpre, 50,    0, 45, 1, CRITICAL_REGION, 0},
    {0,            0,   Vpre, 50,   45, 85, 1, CRITICAL_REGION, 0},
};

/*! \brief discharge mode config table*/
const charge_region_t headset_discharge_mode_config_table[] =
{
    {0, 4200, 4350, 100, -40, -20, 1, NORMAL_REGION, 0},
    {0, 4200, 4350, 100, -20,  60, 1, NORMAL_REGION, 0},
    {0, 4200, 4350, 100,  60,  85, 1, NORMAL_REGION, 0},      
    {0, 3500, 4200, 50,  -40, -20, 1, NORMAL_REGION, 0},
    {0, 3500, 4200, 50,  -20,  60, 1, NORMAL_REGION, 0},
    {0, 3500, 4200, 50,   60,  85, 1, NORMAL_REGION, 0},
    {0, 3300, 3500, 50,  -40, -20, 1, CRITICAL_REGION, 0},
    {0, 3300, 3500, 50,  -20,  60, 1, CRITICAL_REGION, 0},
    {0, 3300, 3500, 50,   60,  85, 1, CRITICAL_REGION, 0},
    {0,    0, 3300, 50,  -40, -20, 1, SAFETY_REGION, 0},
    {0,    0, 3300, 50,  -20,  60, 1, SAFETY_REGION, 0},
    {0,    0, 3300, 50,   60,  85, 1, SAFETY_REGION, 0},
};

void HeadsetNotifyBatteryLow(void)
{
    if(Charger_IsConnected())
    {
        return;
    }

    DEBUG_LOG_INFO("HeadsetNotifyBatteryLow");
    MessageSendLater(&regionData.task, REGION_MESSAGE_BATTERY_LOW, 0, SEC_TO_MS(60));
    regionData.batteryLowNotifying = TRUE;
}

void HeadsetDisableBatteryLowNotify(void)
{
    DEBUG_LOG_INFO("HeadsetDisableBatteryLowNotify");
    MessageCancelAll(&regionData.task, REGION_MESSAGE_BATTERY_LOW);
    regionData.batteryLowNotifying = FALSE;
}

static void headsetTransitionHandler(uint8 old_region_enum, uint8 new_region_enum)
{
    UNUSED(old_region_enum);

    if(!Charger_IsConnected())
    {
        if(headset_discharge_mode_config_table[new_region_enum].region_type == CRITICAL_REGION)
        {
            if(!regionData.batteryLowNotifying)
            {
                HeadsetNotifyBatteryLow();
            }
        }
        else
        {
            HeadsetDisableBatteryLowNotify();
        }
    }
}

/*! \brief battery region component various state handlers*/
const battery_region_handlers_t headset_region_handlers =
{
    {NULL},
    {NULL},
    {headsetTransitionHandler}
};

const charge_region_t* HeadsetRegion_GetChargeModeConfigTable(unsigned* table_length)
{
    *table_length = ARRAY_DIM(headset_charge_mode_config_table);
    return headset_charge_mode_config_table;
}

const charge_region_t* HeadsetRegion_GetDischargeModeConfigTable(unsigned* table_length)
{
    *table_length = ARRAY_DIM(headset_discharge_mode_config_table);
    return headset_discharge_mode_config_table;
}

const battery_region_handlers_t* HeadsetRegion_GetRegionHandlers(void)
{
    return &headset_region_handlers;
}

static void headsetRegionMsgHandler(Task task, MessageId id, Message message)
{
    UNUSED(task);
    UNUSED(message);
    DEBUG_LOG_INFO("headsetRegionMsgHandler id = 0x%X", id);

    switch(id)
    {
        case REGION_MESSAGE_BATTERY_LOW:
        {
            DEBUG_LOG_INFO(" - REGION_MESSAGE_BATTERY_LOW");

            appNotifyPowerLow();

            HeadsetNotifyBatteryLow();
        }
        break;
        default:
        {
            DEBUG_LOG_INFO(" - Unhandled headsetRegionMsgHandler message 0x%x\n", id);
        }
        break;
    }
}

void HeadsetRegionInit(void)
{
    regionData.task.handler = headsetRegionMsgHandler;
}
